<template>
  <div class="findPassword-page">
    <login-page-header />
    <div class="findPassword-page-main">
      <a-button class="close-btn iconfont icon-with-btn" type="text" @click="router.replace('/login')">
        <i class="iconfont icon-close-line"></i>
      </a-button>
      <!-- 第一步 -->
      <div v-if="pageType === 1" class="form-wrapper">
        <div class="title">找回密码</div>
        <a-form ref="findPasswordFromRef" class="form" :model="findPasswordFrom" :rules="findPasswordRules" @finish="findPasswordFinish">
          <a-form-item name="tel">
            <a-input
              v-model:value="findPasswordFrom.tel"
              v-trim
              class="tel-input"
              size="large"
              addon-before="+86"
              :maxlength="11"
              placeholder="请输入手机号"
            />
          </a-form-item>
          <a-form-item name="code">
            <div class="auth-code-wrapper">
              <a-input v-model:value="findPasswordFrom.code" v-trim size="large" placeholder="请输入验证码" :maxlength="8" />
              <div class="verification-img"><img :src="accountKaptcha" alt="" @click="getKaptchaFn()" /></div>
            </div>
          </a-form-item>
          <a-form-item>
            <a-button :loading="stepOneLoading" size="large" type="primary" html-type="submit" class="step-btn">下一步</a-button>
          </a-form-item>
        </a-form>
      </div>
      <!-- 第二步 -->
      <div v-else-if="pageType === 2" class="form-wrapper">
        <div class="title">短信验证</div>
        <a-form ref="smsFromRef" class="form" :model="smsFrom" :rules="smsFromRules" @finish="smsFromFinish">
          <a-form-item name="tel" class="telNumber">
            <a-input
              v-model:value="findPasswordFrom.tel"
              v-trim
              class="tel-input"
              size="large"
              addon-before="+86"
              :maxlength="11"
              placeholder="请输入手机号"
              disabled
            />
          </a-form-item>
          <a-form-item name="code">
            <div class="auth-code-wrapper">
              <a-input v-model:value="smsFrom.code" v-trim size="large" :maxlength="8" placeholder="请输入验证码" />
              <a-button size="large" :disabled="counter ? true : false" @click="sendSms">
                <div class="btn-code">{{ counter ? counter + 's' : '获取验证码' }}</div>
              </a-button>
            </div>
          </a-form-item>
          <a-form-item>
            <a-space>
              <a-button size="large" type="primary" html-type="submit" class="step-btn">下一步</a-button>
              <a-button size="large" class="step-btn" @click="changeType(1)">上一步</a-button>
            </a-space>
          </a-form-item>
        </a-form>
      </div>
      <!-- 第三步 -->
      <div v-else-if="pageType === 3" class="form-wrapper">
        <div class="title">新密码</div>
        <a-form ref="newPasswordRef" class="form" :model="newPasswordFrom" :rules="newPasswordRules" @finish="newPasswordFinish">
          <a-form-item name="newPassWord">
            <a-input-password
              v-model:value="newPasswordFrom.newPassWord"
              v-trim
              size="large"
              :maxlength="15"
              placeholder="请输入新密码"
              @input="newPasswordFrom.newPassWord = newPasswordFrom.newPassWord.replace(/\s+/g, '')"
            />
          </a-form-item>
          <a-form-item name="confirmPassWord">
            <a-input-password
              v-model:value="newPasswordFrom.confirmPassWord"
              v-trim
              size="large"
              placeholder="请输入确认密码"
              :maxlength="15"
              @input="newPasswordFrom.confirmPassWord = newPasswordFrom.confirmPassWord.replace(/\s+/g, '')"
            />
          </a-form-item>
          <a-form-item>
            <a-button :loading="newPasswordLoading" size="large" type="primary" html-type="submit" class="step-btn">确定</a-button>
          </a-form-item>
        </a-form>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { FormInstance, message } from 'ant-design-vue'
  import type { Rule } from 'ant-design-vue/es/form'
  import { regex, useCountDown, useSM4 } from 'g6-fn'
  import { onMounted, reactive, ref } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRouter } from 'vue-router'

  import { SM4_KEY } from '@/config'
  import { loginApi } from '@/services/api'

  import LoginPageHeader from '../components/LoginPageHeader.vue'

  const router = useRouter()
  const { encrypt } = useSM4(SM4_KEY)

  const smsFromRef = ref<FormInstance>()
  const newPasswordRef = ref<FormInstance>()

  /**
   * 切换步骤
   * pageType 1:找回密码  2：短信验证  3： 新密码   4:修改成功
   */
  const pageType = ref<Number>(1)
  function changeType(type: Number) {
    pageType.value = type
    if (type === 1) {
      getKaptchaFn()
    }
  }

  /**
   * 图形验证
   */
  const config = {
    isResponseAll: true,
    headers: {
      'Kaptchat-Type': 'FORGET_PASSWORD'
    },
    responseType: 'arraybuffer'
  }
  const accountKaptcha = ref('')
  // //生成随机验证码
  // const generateBase64Image = (randomString: number) => {
  //   // 创建一个canvas元素
  //   const canvas = document.createElement('canvas')
  //   const ctx = canvas.getContext('2d') as any

  //   // 设置canvas尺寸
  //   canvas.width = 100
  //   canvas.height = 40

  //   // 设置背景色和字体样式
  //   ctx.fillStyle = '#f5f5f5'
  //   ctx.fillRect(0, 0, canvas.width, canvas.height)
  //   ctx.font = '20px Arial'
  //   ctx.fillStyle = '#333'
  //   ctx.textAlign = 'center'
  //   ctx.textBaseline = 'middle'

  //   // 将随机字符串绘制到canvas
  //   ctx.fillText(randomString, canvas.width / 2, canvas.height / 2)

  //   // 将canvas转换成base64
  //   return canvas.toDataURL('image/png')
  // }
  const { runAsync: getKaptchaFn } = useRequest<{ headers: { 'security-code': string }; data: any }>(
    () => loginApi.getKaptcha({}, config),
    {
      throttleInterval: 200,
      onSuccess: res => {
        findPasswordFrom.securityCode = res.headers['security-code']
        console.log(res.data, 'res.data')
        // accountKaptcha.value = generateBase64Image(res.data.int)
        accountKaptcha.value =
          'data:image/png;base64,' + btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))
      }
    }
  )
  onMounted(() => {
    getKaptchaFn()
  })

  /**
   * 第一步
   */
  const findPasswordFrom = reactive({
    tel: '',
    code: '',
    securityCode: '',
    kaptchatType: 'FORGET_PASSWORD'
  })
  const findPasswordRules: Record<string, Rule[]> = {
    tel: [
      { required: true, message: '请输入手机号' },
      {
        pattern: regex.phone,
        message: '请输入正确的手机号'
      }
    ],
    code: [{ required: true, trigger: 'change', message: '请输入验证码' }]
  }
  const { loading: stepOneLoading, runAsync: runCheckVerifyCode } = useRequest<{ headers: { 'security-img-code': string }; data: any }>(
    loginApi.checkVerifyCode,
    {
      onSuccess(res) {
        if (findPasswordFrom.tel !== smsFrom.tel && smsFrom.tel) {
          smsFromRef.value?.validateFields('checkPass')
          newPasswordRef.value?.validateFields('checkPass')
        }
        smsFrom.tel = findPasswordFrom.tel
        smsFrom.securityImgCode = res.headers['security-img-code']
        changeType(2)
        findPasswordFrom.code = ''
      },
      onError() {
        findPasswordFrom.code = ''
        getKaptchaFn()
      }
    }
  )
  const findPasswordFinish = () => runCheckVerifyCode(findPasswordFrom)

  /**
   * 第二步
   */
  const smsFrom = reactive({
    tel: '',
    code: '',
    securityImgCode: '', // 图形验证码Code
    securityCode: ''
  })
  const smsFromRules: Record<string, Rule[]> = {
    tel: [
      { required: true, message: '请输入手机号' },
      {
        pattern: regex.phone,
        message: '请输入正确的手机号'
      }
    ],
    code: [{ required: true, trigger: 'change', message: '请输入验证码' }]
  }
  const { counter, start } = useCountDown()
  const { runAsync: runSendSms } = useRequest<{ headers: { 'security-code': string }; data: any }>(loginApi.sendSms, {
    onSuccess(res) {
      smsFrom.securityCode = res.headers['security-code']
      message.success('短信验证码发送成功')
      start(60)
    },
    onError(err: any) {
      if (err.code === 'AUTH-100007') {
        changeType(1)
      }
      // message.error(err.message)
    }
  })
  const sendSms = async () => {
    let params = {
      messageType: 3
    }
    Object.assign(params, smsFrom)
    runSendSms(params)
  }
  const { runAsync: runCheckSmsCode } = useRequest<{ headers: { 'security-sms-code': string }; data: any }>(loginApi.checkSmsCode, {
    onSuccess(res) {
      newPasswordFrom.securitySmsCode = res.headers['security-sms-code']
      newPasswordFrom.tel = smsFrom.tel
      changeType(3)
    }
  })
  const smsFromFinish = () => runCheckSmsCode(smsFrom)

  /**
   * 第三步
   */
  const newPasswordFrom = reactive({
    newPassWord: '',
    confirmPassWord: '',
    securitySmsCode: '', // 短信验证码成功标识
    tel: '' // 手机号
  })
  //密码校验规则
  const passwordVerificaRule = (value: string) => {
    // 检查密码长度
    if (!value) {
      return Promise.reject('请输入密码')
    } else if (value.length < 8 || value.length > 15) {
      return Promise.reject('密码的长度为8-15位')
    }

    // 定义正则表达式，要求包含大、小写字母、数字和特殊字符中的三项
    const regex =
      // /^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_])|(?=.*[a-z])(?=.*\d)(?=.*[\W_])|(?=.*[A-Z])(?=.*\d)(?=.*[\W_])).+$/
      /^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_])|(?=.*[a-z])(?=.*\d)(?=.*[\W_])|(?=.*[A-Z])(?=.*\d)(?=.*[\W_]))[^\u4e00-\u9fa5\u3040-\u30FF\uAC00-\uD7AF]+$/

    if (!regex.test(value)) {
      return Promise.reject('密码至少包含大、小写字母、数字和特殊字符中的三项')
    }

    return Promise.resolve()
  }
  //校验密码
  let validatePWS = async (rule: Rule, value: string) => {
    if (value === '') {
      return Promise.reject('请输入新密码')
    }
    // return PubCheckPWS(value)
    return passwordVerificaRule(value)
  }
  //确认密码
  let validateAckPWS = async (rule: Rule, value: string) => {
    if (value === '') {
      return Promise.reject('请输入确认密码')
    }
    if (value !== newPasswordFrom.newPassWord) {
      return Promise.reject('两次输入的新密码不一致')
    }
    return Promise.resolve()
  }
  const newPasswordRules: Record<string, Rule[]> = {
    newPassWord: [{ required: true, trigger: 'change', validator: validatePWS }],
    confirmPassWord: [{ required: true, trigger: 'change', validator: validateAckPWS }]
  }
  const { loading: newPasswordLoading, runAsync: runNewPasswordFinish } = useRequest(loginApi.forgetPassword, {
    onSuccess() {
      router.replace('/success')
    }
  })
  const newPasswordFinish = () => {
    let params = JSON.parse(JSON.stringify(newPasswordFrom))
    // 加密密码
    params.confirmPassWord = encrypt(params.confirmPassWord)
    params.newPassWord = encrypt(params.newPassWord)
    runNewPasswordFinish(params)
  }
</script>

<style lang="less" scoped>
  @import '../styles/index.less';

  .findPassword-page {
    display: flex;
    min-width: @min-width;
    height: 100%;
    flex-direction: column;

    .ant-btn-primary {
      color: #fff;
      background: linear-gradient(180deg, #81b1ff 0%, #1868e9 100%);
      border: none;
      box-shadow: 0 2px #0000000b;
    }

    .findPassword-page-main {
      position: relative;
      display: flex;
      justify-content: center;
      // align-items: center;
      width: 100vw;
      flex: 1;

      .title {
        margin-bottom: 56px;
        font-size: 20px;
        font-weight: 700;
      }

      .form-wrapper {
        padding: 0 16px;
        margin-top: 200px;
        width: 462px;

        .form {
          .ant-form-item {
            margin-bottom: 40px;

            &:nth-child(3) {
              margin-bottom: 0;
              .auth-code-wrapper();
            }
          }
        }
      }
    }
  }
</style>
